package controllers

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	"github.com/astaxie/beego"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"

	"conf"
	"models"
	"models/gender"
	"models/relation"
	"models/response"
)

type BabyUpdateController struct {
	beego.Controller
}

func (this *BabyUpdateController) Post() {

	var result response.Response

	targetBabyId := this.GetString("bid")
	//fmt.Println("targetBabyId:", targetBabyId)
	if targetBabyId == "" {
		result.Message = response.Info_Error_BabyIdIsNull
		result.Ret = response.Code_Error_BidIsNull
		this.Ctx.WriteString(result.FormatJsonString())
		return
	}

	isExistsInDb, existsBaby := isBabyExistsDB(targetBabyId)
	if !isExistsInDb {
		result.Message = response.Info_Error_TargetNotExists
		result.Ret = response.Code_Error_TargetNotExists
		this.Ctx.WriteString(result.FormatJsonString())
	}

	var postJson string
	postJson = fmt.Sprintf("%s", this.Ctx.RequestBody)
	//fmt.Println("post json :", postJson)
	if postJson == "" {
		result.Message = response.Info_Error_ParamError
		result.Ret = response.Code_Error_ParamError
		this.Ctx.WriteString(result.FormatJsonString())
		return
	}

	var updataBabyField models.Baby
	json.Unmarshal([]byte(postJson), &updataBabyField)

	fmt.Println("updataBabyField :", updataBabyField)

	if updataBabyField.Name != "" &&
		!strings.EqualFold(updataBabyField.Name, existsBaby.Name) {
		existsBaby.Name = updataBabyField.Name

	}

	if updataBabyField.Nick != "" &&
		!strings.EqualFold(updataBabyField.Nick, existsBaby.Nick) {
		existsBaby.Nick = updataBabyField.Nick
	}

	if updataBabyField.Header != "" &&
		!strings.EqualFold(updataBabyField.Header, existsBaby.Header) {
		existsBaby.Header = updataBabyField.Header
	}

	if updataBabyField.Gender != gender.Unknow &&
		updataBabyField.Gender == existsBaby.Gender {
		existsBaby.Gender = updataBabyField.Gender
	}

	if updataBabyField.Birthday != "" &&
		!strings.EqualFold(updataBabyField.Birthday, existsBaby.Birthday) {
		existsBaby.Birthday = updataBabyField.Birthday
	}

	if len(updataBabyField.Relations) > 0 {
		fmt.Println("updataBabyField.Relations:", updataBabyField.Relations)
		for kR, vR := range updataBabyField.Relations {
			fmt.Print("k:%s, v:%s:", kR, vR)
			oldValue := existsBaby.Relations[kR]
			if vRIntValue, err := strconv.Atoi(fmt.Sprintf("%v", vR)); err == nil {
				if oldValue != vRIntValue {
					if vRIntValue == relation.Unknow {
						delete(existsBaby.Relations, kR)
					} else {
						existsBaby.Relations[kR] = vRIntValue
					}

					fmt.Println("changed baby :", existsBaby)
				}
			}
		}
	}

	fmt.Println("baby :", existsBaby)

	session, err := mgo.Dial(config.DataBaseIP)
	if err != nil {
		result.Message = response.Info_Error_OperationFailed
		result.Ret = response.Code_Error_OperationFailed
		this.Ctx.WriteString(result.FormatJsonString())
		return
	}

	defer session.Close()

	session.SetMode(mgo.Monotonic, true)

	c := session.DB(config.DataBaseName).C(config.DataTableBaby)
	err = c.UpdateId(bson.ObjectIdHex(targetBabyId), &existsBaby)
	if err != nil {
		result.Message = response.Info_Error_OperationFailed
		result.Ret = response.Code_Error_OperationFailed
		this.Ctx.WriteString(result.FormatJsonString())
		return
	}

	result.Message = response.Info_Success
	result.Ret = response.Code_Success

	this.Ctx.WriteString(result.FormatJsonString())
}

func isBabyExistsDB(babyId string) (bool, models.Baby) {
	result := models.Baby{}
	session, err := mgo.Dial(config.DataBaseIP)
	if err != nil {
		return false, result
	}

	defer session.Close()

	session.SetMode(mgo.Monotonic, true)
	c := session.DB(config.DataBaseName).C(config.DataTableBaby)

	err = c.FindId(bson.ObjectIdHex(babyId)).One(&result)
	if err != nil {
		return false, result
	}

	return true, result
}

func (this *BabyUpdateController) Get() {
	this.Ctx.WriteString("baby update get\n")
}
